home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
MLT_TASK
/
PIBMDOS
/
WRITESXY.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-03-14
|
14KB
|
183 lines
(*----------------------------------------------------------------------*)
(* WriteSXY --- Write text string to specified row/column *)
(*----------------------------------------------------------------------*)
PROCEDURE WriteSXY( S: AnyStr; X: INTEGER; Y: INTEGER; Color: INTEGER );
(*----------------------------------------------------------------------*)
(* *)
(* Procedure: WriteSXY *)
(* *)
(* Purpose: Writes text string at specified row and column *)
(* position on screen. *)
(* *)
(* Calling Sequence: *)
(* *)
(* WriteSXY( S: AnyStr; X: INTEGER; Y: INTEGER; Color: INTEGER );*)
(* *)
(* S --- String to be written *)
(* X --- Column position to write string *)
(* Y --- Column position to write string *)
(* Color --- Color in which to write string *)
(* *)
(* Calls: None *)
(* *)
(*----------------------------------------------------------------------*)
BEGIN (* WriteSXY *)
(* Freeze screen for DoubleDos *)
IF ( MultiTasker = DoubleDos ) THEN
BEGIN
TurnOffTimeSharing;
Get_Screen_Address( Virtual_Screen );
END;
INLINE(
$1E/ { PUSH DS ;Save data segment register}
{;}
{; Check if we're using BIOS.}
{;}
$F6/$06/>WRITE_SCREEN_MEMORY/$01/ { TEST BYTE [>Write_Screen_Memory],1 ;Direct screen write?}
$74/$54/ { JZ Bios ;No -- go use BIOS}
{;}
{; Set up for direct screen write.}
{; Get row position and column positions, and offset in screen buffer.}
{;}
$C4/$3E/>VIRTUAL_SCREEN/ { LES DI,[>Virtual_Screen] ;Get base address of screen}
$8B/$4E/<Y/ { MOV CX,[BP+<Y] ;CX = Row}
$49/ { DEC CX ;Row to 0..Max_Screen_Line-1 range}
$A1/>MAX_SCREEN_COL/ { MOV AX,[>Max_Screen_Col] ;Physical screen width}
$F7/$E1/ { MUL CX ;Row * Max_Screen_Col}
$8B/$5E/<X/ { MOV BX,[BP+<X] ;BX = Column}
$4B/ { DEC BX ;Col to 0..Max_Screen_Col-1 range}
$01/$D8/ { ADD AX,BX ;AX = (Row * Max_Screen_Col) + Col}
$D1/$E0/ { SHL AX,1 ;Account for attribute bytes}
$89/$FB/ { MOV BX,DI ;Get base offset of screen}
$01/$C3/ { ADD BX,AX ;Add computed offset}
$89/$DF/ { MOV DI,BX ;Move result into DI}
$A0/>WAIT_FOR_RETRACE/ { MOV AL,[<Wait_For_Retrace] ;Grab this before changing DS}
$16/ { PUSH SS}
$1F/ { POP DS}
$8D/$B6/>S/ { LEA SI,[BP+>S] ;DS:SI will point to S[0]}
$31/$C9/ { XOR CX,CX ;Clear CX}
$8A/$0C/ { MOV CL,[SI] ;CL = Length(S)}
$E3/$27/ { JCXZ Exit1 ;If string empty, Exit}
$46/ { INC SI ;DS:SI points to S[1]}
$8A/$66/<COLOR/ { MOV AH,[BP+<Color] ;AH = Attribute}
$FC/ { CLD ;Set direction to forward}
$A8/$01/ { TEST AL,1 ;If we don't wait for retrace, ...}
$74/$1A/ { JZ Mono ; use "Mono" routine}
{;}
{; Color routine (used only when Wait_For_Retrace is True) **}
{;}
$BA/>CRT_STATUS/ { MOV DX,>CRT_Status ;Point DX to CGA status port}
$AC/ {GetNext: LODSB ;Load next character into AL}
{ ; AH already has Attr}
$89/$C3/ { MOV BX,AX ;Store video word in BX}
{;}
$EC/ {WaitNoH: IN AL,DX ;Get 6845 status}
$A8/$01/ { TEST AL,1 ;Wait for horizontal}
$75/$FB/ { JNZ WaitNoH ; retrace to finish}
{;}
$FA/ { CLI ;Turn off interrupts}
$EC/ {WaitH: IN AL,DX ;Get 6845 status again}
$A8/$01/ { TEST AL,1 ;Wait for horizontal retrace}
$74/$FB/ { JZ WaitH ; to start}
{;}
$89/$D8/ {Store: MOV AX,BX ;Restore attribute}
$AB/ { STOSW ; and then to screen}
$FB/ { STI ;Allow interrupts}
$E2/$EC/ { LOOP GetNext ;Get next character}
$E9/$62/$00/ { JMP Exit ;Done}
{;}
{; Mono routine (used whenever Wait_For_Retrace is False) **}
{;}
$AC/ {Mono: LODSB ;Load next character into AL}
{ ; AH already has Attr}
$AB/ { STOSW ;Move video word into place}
$E2/$FC/ { LOOP Mono ;Get next character}
{;}
$E9/$5B/$00/ {Exit1: JMP Exit ;Done}
{;}
{; Use BIOS to display string (if Write_Screen is False) **}
{;}
$B4/$03/ {Bios: MOV AH,3 ;BIOS get cursor position}
$B7/$00/ { MOV BH,0}
$55/ { PUSH BP}
$CD/$10/ { INT $10 ;Get current cursor position}
$5D/ { POP BP}
$52/ { PUSH DX ;Save current cursor position}
{;}
$8A/$76/<Y/ { MOV DH,[BP+<Y] ;Get starting row}
$FE/$CE/ { DEC DH ;Drop by one for BIOS}
$8A/$56/<X/ { MOV DL,[BP+<X] ;Get starting column}
$FE/$CA/ { DEC DL ;Drop for indexing}
$FE/$CA/ { DEC DL ;}
$16/ { PUSH SS}
$1F/ { POP DS}
$8D/$B6/>S/ { LEA SI,[BP+>S] ;DS:SI will point to S[0]}
$31/$C9/ { XOR CX,CX ;Clear out CX}
$8A/$0C/ { MOV CL,[SI] ;CL = Length(S)}
$E3/$31/ { JCXZ Bios2 ;If string empty, Exit}
$46/ { INC SI ;DS:SI points to S[1]}
$52/ { PUSH DX ;Save X and Y}
$1E/ { PUSH DS ;Save string address}
$56/ { PUSH SI ;}
$FC/ { CLD ;Forward direction}
{;}
$B4/$02/ {Bios1: MOV AH,2 ;BIOS Position cursor}
$B7/$00/ { MOV BH,0 ;Page zero}
$5E/ { POP SI ;Get S address}
$1F/ { POP DS ;}
$5A/ { POP DX ;X and Y}
$FE/$C2/ { INC DL ;X + 1}
$52/ { PUSH DX ;Save X and Y}
$1E/ { PUSH DS ;Save strin address}
$56/ { PUSH SI}
$51/ { PUSH CX ;Push length}
$55/ { PUSH BP}
$CD/$10/ { INT $10 ;Call BIOS to move to (X,Y)}
$5D/ { POP BP}
$59/ { POP CX ;Get back length}
$5E/ { POP SI ;Get String address}
$1F/ { POP DS ;}
$AC/ { LODSB ;Next character into AL}
$1E/ { PUSH DS ;Save String address}
$56/ { PUSH SI ;}
$51/ { PUSH CX ;Length left to do}
$55/ { PUSH BP}
$B4/$09/ { MOV AH,9 ;BIOS Display character}
$B7/$00/ { MOV BH,0 ;Display page zero}
$8A/$5E/<COLOR/ { MOV BL,[BP+<Color] ;BL = Attribute}
$B9/$01/$00/ { MOV CX,1 ;One character}
$CD/$10/ { INT $10 ;Call BIOS}
$5D/ { POP BP}
$59/ { POP CX ;Get back length}
$E2/$D7/ { LOOP Bios1}
{; ;Remove stuff left on stack}
$5E/ { POP SI}
$1F/ { POP DS}
$5A/ { POP DX}
{;}
$5A/ {Bios2: POP DX ;Restore previous cursor position}
$B7/$00/ { MOV BH,0}
$B4/$02/ { MOV AH,2 ;BIOS set cursor position}
$55/ { PUSH BP}
$CD/$10/ { INT $10}
$5D/ { POP BP}
{;}
$1F); {Exit: POP DS ;Restore DS}
(* Unfreeze screen in DoubleDos *)
IF ( MultiTasker = DoubleDos ) THEN
TurnOnTimeSharing
(* Synchronize screen for TopView *)
ELSE IF ( MultiTasker = TopView ) THEN
IF Write_Screen_Memory THEN
Sync_Screen( PRED( ( PRED( Y ) * Max_Screen_Col + X ) SHL 1 ) , LENGTH( S ) );
END (* WriteSXY *);